//////////////////////////////////////////////////////////////////////        
// SysVolume.cpp: implementation of the CSysVolume class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "VolumeCtrl.h"


//======================================================================
//Macro define

//Registry KEY
#define BASE_KEY                     HKEY_CURRENT_USER
#define SUB_KEY                        TEXT("ControlPanel/Volume")
#define VALUE_VOLUME                TEXT("Volume")
#define VALUE_SCREEN                TEXT("Screen")
#define VALUE_KEY                    TEXT("key")
#define VALUE_MUTE                    TEXT("Mute")


//For the screen tap and the key click
#define VOL_VALUE_MUTE                0
#define VOL_VALUE_LOUD                65538
#define VOL_VALUE_SOFT                1


//The bit for sound
#define BIT_EVENT                    0x4
#define BIT_APPLICATION                0x2
#define BIT_NOTIFICATION            0x1
//======================================================================
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSysVolume::CSysVolume()
{
	m_Reg.Create(BASE_KEY, SUB_KEY);
}

CSysVolume::~CSysVolume()
{

}





//---------------------------------------------------------------------
//Description:
//    Apply the volume
//---------------------------------------------------------------------
BOOL CSysVolume::Apply()
{
	typedef void (WINAPI *DLL_AUDIOUPDATEFROMREGISTRY)();

	DLL_AUDIOUPDATEFROMREGISTRY Dll_AudioUpdateFromRegistry = NULL; 
	HINSTANCE hCoreDll = LoadLibrary(TEXT("coredll.dll")); 
	if (hCoreDll) 
	{ 
		Dll_AudioUpdateFromRegistry = (DLL_AUDIOUPDATEFROMREGISTRY)GetProcAddress(hCoreDll, _T("AudioUpdateFromRegistry")); 
		if (Dll_AudioUpdateFromRegistry) 
		{ 
			(Dll_AudioUpdateFromRegistry)(); 
		} 
		else
		{
			return FALSE;
		}
		FreeLibrary(hCoreDll); 
	} 
	else
	{
		return FALSE;
	}
	return TRUE;
}



//---------------------------------------------------------------------
//Description:
//    Enable the sound for events
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundEvent(BOOL bEnable)
{
	if(m_Reg.IsOK() != TRUE)
	{
		return FALSE;
	}

	DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);

	if(bEnable == TRUE)
	{
		dwVal |= BIT_EVENT;
	}
	else
	{
		dwVal &= ~BIT_EVENT;
	}

	m_Reg.SetDW(VALUE_MUTE,dwVal);

	return Apply();
}


//---------------------------------------------------------------------
//Description:
//    Enable the sound for application
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundApplication(BOOL bEnable)
{
	if(m_Reg.IsOK() != TRUE)
	{
		return FALSE;
	}

	DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);

	if(bEnable == TRUE)
	{
		dwVal |= BIT_APPLICATION;
	}
	else
	{
		dwVal &= ~BIT_APPLICATION;
	}

	m_Reg.SetDW(VALUE_MUTE,dwVal);

	return Apply();
}


//---------------------------------------------------------------------
//Description:
//    Enable the sound for notifications. If the sound of application is
//mute, the sound of  notification is mute too.
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundNotification(BOOL bEnable)
{
	if(m_Reg.IsOK() != TRUE)
	{
		return FALSE;
	}

	DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);

	if(bEnable == TRUE)
	{
		dwVal |= BIT_NOTIFICATION;
	}
	else
	{
		dwVal &= ~BIT_NOTIFICATION;
	}

	m_Reg.SetDW(VALUE_MUTE,dwVal);

	return Apply();
}


//---------------------------------------------------------------------
//Description:
//    Set the key click volume
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolumeKeyClick(VolumeModeType volMode)
{

	DWORD dwVol = 0;

	switch(volMode)
	{
	case VOL_SOFT:
		dwVol = VOL_VALUE_SOFT;
		break;
	case VOL_LOUD:
		dwVol = VOL_VALUE_LOUD;
		break;
	case VOL_MUTE:
		dwVol = VOL_VALUE_MUTE;
		break;
	}

	if(m_Reg.IsOK() != TRUE)
	{
		return FALSE;
	}
	m_Reg.SetDW(VALUE_KEY,dwVol);

	return Apply();
}


//---------------------------------------------------------------------
//Description:
//    Set the screen tap volume
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolumeScreenTap(VolumeModeType volMode)
{    
	DWORD dwVol = 0;

	switch(volMode)
	{
	case VOL_SOFT:
		dwVol = VOL_VALUE_SOFT;
		break;
	case VOL_LOUD:
		dwVol = VOL_VALUE_LOUD;
		break;
	case VOL_MUTE:
		dwVol = VOL_VALUE_MUTE;
		break;
	}

	if(m_Reg.IsOK() != TRUE)
	{
		return FALSE;
	}
	m_Reg.SetDW(VALUE_SCREEN,dwVol);
	return Apply();
}


//---------------------------------------------------------------------
//Description:
//    Set the volume. 
//
//Parameters:
//    dwVol: The volume to set. And the range is MIN_VOLUME ~  MAX_VOLUME
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolume(DWORD dwVol)
{
	if(dwVol < MIN_VOLUME || dwVol > MAX_VOLUME)
	{
		return FALSE;
	}
	m_Reg.SetDW(VALUE_VOLUME,dwVol);
	return Apply();
}
